/**
 * Copyright (C) 2015 Baidu, Inc. All Rights Reserved.
 */
package imserver.dao;

import java.io.Serializable;
import java.util.Collection;
import java.util.List;

import javax.annotation.Resource;

import org.apache.log4j.Logger;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.springframework.stereotype.Repository;

import imserver.common.util.DaoException;
import imserver.common.util.GenericsUtils;



/**
 * @author zhanghongbin01 数据库操作接口实现
 * @param <T>
 */
@Repository
public class BaseDaoImpl<T> implements BaseDao<T> {
    private Logger log = Logger.getLogger(BaseDaoImpl.class);

    @Resource
    private SessionFactory sessionFactory;
    @SuppressWarnings("unchecked")
    protected Class<T> entityClass = GenericsUtils.getSuperClassGenricType(this.getClass());
    
    @Override
    public void save(T entity) throws DaoException {
        this.getSession().save(entity);
    }

  
    @Override
    public void save(Collection<T> entitys) {

    }

    @Override
    public void saveOrUpdate(T entity) throws DaoException {
        this.getSession().saveOrUpdate(entity);
    }

    @Override
    public void delete(Serializable id) {

    }

    @Override
    public void delete(T entity) throws DaoException {
        this.getSession().delete(entity);
    }

    @Override
    public void delete(Collection<T> entitys) {

    }

    @Override
    public void update(T entity) {

    }

    /**
     * 获取数据库操作的会话session
     * 
     * @see com.rebook.dao.BaseDao#getSeesion()
     */
    @Override
    public Session getSession() throws DaoException {
        Session session = null;
        if (sessionFactory != null) {
            //只能使用getCurrentSession来获取Session，否则无法管理事务
            session = sessionFactory.getCurrentSession();
        } else {
            log.warn("get SessionFactory error");
            throw new DaoException();
        }
        return session;
    }

    /**
     *  执行sql语句
     * @see com.rebook.dao.BaseDao#exexuteSQL(java.lang.String)
     */
    @Override
    public void exexuteSQL(String sql) throws DaoException {
       Session session = getSession();
       Transaction tc = session.beginTransaction();
       Query query = session.createQuery(sql);
       query.executeUpdate();
       tc.commit();
    }

    
    @SuppressWarnings("unchecked")
    @Override
    public T get(Serializable id) throws DaoException {
         return (T) this.getSession().get(entityClass, id);
    }
    
    @SuppressWarnings("unchecked")
    public List<T> get(String sql) throws DaoException{
        Query query = this.getSession().createQuery(sql);
        return query.list();
    }
    
    
    /**
     * 构建SQL查询语句
     * @param query
     * @param parameters
     * @return
     * @throws DaoException
     */
    public Query buildQuery(Query query,Object[] parameters) throws DaoException{
        if(query !=null && parameters.length>0)
        for(int i=0;i<parameters.length;i++){
            query.setParameter(i, parameters[i]);
        }else{
            throw new DaoException("SQL语句错误");
        }
        return query;
    }

    @SuppressWarnings("unchecked")
    @Override
    public List<T> get() throws DaoException {
        String hql = "from "+entityClass.getSimpleName();
        System.out.println(hql);
        Session session = getSession();
        Query query = session.createQuery(hql);
        return query.list();
    }

    @SuppressWarnings("unchecked")
    @Override
    public List<T> execute(String sql, Object[] paramtes) throws DaoException {
        Session session = getSession();
        Query query = session.createQuery(sql);
        buildQuery(query, paramtes);
        return query.list();
    }

    @SuppressWarnings("unchecked")
    @Override
    public T executeUniq(String sql, Object[] paramtes) throws DaoException {
        Session session = getSession();
        Query query = session.createQuery(sql);
        buildQuery(query, paramtes);
        return (T)query.uniqueResult();
    }


    /** 
     * 方法重写
     * @throws DaoException 
     * @see com.rebook.dao.BaseDao#getTop(int)
     */
    @SuppressWarnings("unchecked")
    @Override
    public List<T> getTop(int maxNum) throws DaoException {
        Query query = getSession().createQuery("from "+entityClass.getSimpleName());
        query.setMaxResults(maxNum);
        return query.list();
    }
}
